#ifndef PYTABLESTABLE_H_
#define PYTABLESTABLE_H_

#include <string>
#include <hdf5.h>

#include "table_exception.hpp"

namespace pyt {
  class parameters {
  public:
    static const float   BUF_TO_CHUNK_RATIO;
    static const hsize_t DEFAULT_NROWS;
  };
  
  const float   parameters::BUF_TO_CHUNK_RATIO = 10000.;
  const hsize_t parameters::DEFAULT_NROWS      = 100000;
  
  template <class T> class table {
  public:
    virtual ~table();
    // void set_buffer_size(hsize_t size) throw() {
    //   _bufsize = size; 
    // }

    // hsize_t get_buffer_size(hsize_t size) throw() {
    //   return _bufsize;
    // }

    virtual hsize_t nrows() = 0; 
    herr_t status() { 
      return _status;
    }
    virtual herr_t read_row(T& row) {
    throw table_exception("Illegal call of abstract method: table::read_row()");
    }
    virtual herr_t append(T& row) {
      throw table_exception("Illegal call of abstract method: table::append()");
    }
    virtual void reset() {
      throw table_exception("Illegal call of abstract method: table::reset()");
    }

  protected:
    table(const std::string& name, const std::string& tbl_name);
    
    std::string _fname;
    std::string _tblname;
    hid_t       _idfile;
    hid_t       _idtbl;
    hid_t       _idfsp;
    int         _rank;
    herr_t      _status;
    hsize_t     _nrows;
    hsize_t     _irow;
    hsize_t     _offset;
    hsize_t     _chunkbytes;
    hsize_t     _chunksize;
    hsize_t     _chunkrank;
    hsize_t     _bufsize;
    hid_t       _cparms;
    T*          _buf;

  };

  template <class T> table<T>::table(const std::string& fname, const std::string& tblname) : 
    _fname(fname),
    _tblname(tblname),
    _idfile(0),
    _idtbl(0),
    _idfsp(0),
    _status(0),
    _nrows(0),
    _irow(0),
    _offset(0),
    _chunkbytes(0),
    _chunksize(0),
    _chunkrank(0),
    _bufsize(parameters::DEFAULT_NROWS),
    _cparms(0),
    _buf(NULL)
  {}

  template <class T> table<T>::~table() {}
}


#endif //PYTABLESTABLE_H_
